package design.patterns.command;

import design.patterns.state.State;

import java.util.Observer;


/**
 * Created with IntelliJ IDEA.
 * User: nuno-rafael-figueiredo
 * Date: 04-03-2014
 * Time: 14:09
 */
public abstract class Command<TResult> extends State.Context implements ICommand{
    private TResult result;

    public TResult getResult() {
        return result;
    }

    protected void setResult(TResult result) {
        this.result = result;
    }

    @Override
    public void execute() {
        start();
        try{
            protectedExecute();
            finish();
        }catch(Exception e){
            abort(e);
        }
    }

    private void abort(Exception e) {
        setState(ABORTED, e);
    }

    private void finish() {
        setState(FINISHED);
    }

    private void start() {
        setState(STARTED);
    }

    protected abstract void protectedExecute() throws Exception;

    public Command<TResult> onFinished(Observer observer) {
        on(FINISHED, observer);
        return this;
    }

    public Command<TResult> onAborted(Observer observer) {
        on(ABORTED, observer);
        return this;
    }
}
